﻿<?xml version="1.0" encoding="utf-8" ?>
<Lab>

	<property id="DisplayName">
		<para>
			To specify the name of a <see cref="Lab"/> you can either pass the name as an argument to
			one of the base <see cref="Lab"/> constructors that accept it, or you can adorn your class
			with <see cref="DisplayNameAttribute"/>.
		</para>
		<alert type="tip">
			The <strong>DisplayNameAttribute</strong> class in .NET is not supported by Silverlight, so a new
			<see cref="DisplayNameAttribute" /> has been defined for Silverlight labs.
		</alert>
		<para>
			Explicitly passing in the name to a constructor takes precedence over <see cref="DisplayNameAttribute"/>.
			By default, when the attribute is specified and one of the base <see cref="Lab"/> constructors that do not
			accept a name parameter is used, then the simple type name of the class becomes the lab's <see cref="DisplayName"/>.
		</para>
		<alert type="info">
			When detected, "labs" and "lab" suffixes are automatically stripped, ignoring case.
		</alert>
	</property>

	<property id="Description">
		<para>
			To specify a description for a <see cref="Lab"/>, add the <see cref="DescriptionAttribute"/>
			to your class.
		</para>
	</property>

	<property id="Categories">
		<para>
			To specify <see cref="Categories"/> for a <see cref="Lab"/>, add the <see cref="CategoryAttribute"/>
			to your class.  The category string may contain one or more periods (.) to separate individual
			categories.  The category string may start with a period, in which case the full namespace of
			your class will be parsed into categories and inserted into the <see cref="Categories"/> list
			before the categories specified in the category string.  By default, when no <see cref="CategoryAttribute"/>
			is specified, the full namespace of your class, if any, is parsed as the entire category string.
		</para>
		<alert type="info">
			When detected, "labs" and "lab" suffixes are automatically stripped, ignoring case.
		</alert>
	</property>

	<type id="Lab">
		<remarks kind="intro">
			<para>
				The environment in which a <see cref="Lab"/> runs is hosted by a <see cref="LabController" />.
				All labs defined in the assembly in which the derived <see cref="LabController"/> class is
				defined are, optionally, discovered at runtime via the Managed Extensibility Framework (MEF).
				This alleviates having to manually register labs or to maintain a list of labs to be executed.
				Labs can also be organized into a <see cref="LabCatalog" />, providing more control over the
				particular labs that the <see cref="LabController"/> can discover and execute.
			</para>
			<para>
				Every <see cref="Lab"/> has a <see cref="DisplayName"/>; however, the <see cref="Description"/> and
				<see cref="Categories"/> are optional.
			</para>
		</remarks>
		<remarks kind="remainder">
			<para>
				Individual labs should be designed as either a learning experience for the author or as a
				learning experience for consumers.  For the author, labs provide a way to learn about how
				components behave and how best to achieve desired results.  This is especially useful with
				components for which no recommended best practices or documentation exists.  For consumers, a
				<see cref="Lab"/> is an executable example and recommendation of how particular components are
				intended to work together or how a particular compnent is meant to behave under certain
				conditions.  Furthermore, a lab's code can be included in API documentation for consumers
				and delivered along with the labs' executable.
			</para>
			<alert type="tip">
				Try to design labs independently of the UI in which they will be executed, unless of course the
				primary focus of a <see cref="Lab"/> is to experiment with a particular UI.  For labs that aren't
				UI-dependent, use the tracing methods provided by the base <see cref="LabTraceSource"/> class or
				the .NET Framework's <see cref="Trace"/> class to submit output to the <see cref="LabController"/>.
			</alert>
			<para>
				<see cref="Lab"/> can be used as a regression test, much like a unit test.  This works because
				labs are written against components under the assumption that they will behave as intended.
				Some breaking changes will be detected by labs, thus they can be used as a broad regression test
				suite; however, unit tests are more suitable for deep regression testing because they can detect
				breaking changes that only affect unexceptional output, whereas a lab is only guaranteed to
				highlight breaking changes made to names and method signatures or to changes that cause exceptions
				to be thrown due to conflicts in the way in which modified components are being utilized.
			</para>
			<para>
				Labs and unit tests differ in a few other ways, as follows.
			</para>
			<list type="number">
				<item>
					Labs typically cover the usage of many different components and not just a single logical unit.
					In this regard, labs are more like integration tests rather than unit tests.
				</item>
				<item>
					The primary goal of a <see cref="Lab"/> is to run experiments that test and illustrate actual,
					observable behavior, whereas unit tests are primarily designed to test intended specifications
					before and during development; therefore, when a unit test fails assertions it proves that a component
					does not satisfy the intended specification, whereas the failure of a lab reveals that a consumer's
					expectations are in fact wrong, whether it indicates a bug in the components being tested or not.
					The action taken after failure depends upon how the labs are being used.  Sometimes the same
					action can be taken as with unit tests; e.g., fix the bug.  In other cases, for example when it's
					not your own components under experimentation, you may find it necessary to report the bug and
					find a workaround.  The lab then acts as executable documentation of the unexpected behavior.
				</item>
				<item>
					Labs are focused on using public APIs only, without the use of accessors and mocks.  In this way,
					they are beneficial to all consumers of the components under experimentation and not just for the
					developers that are creating them.  Note, however, that using
					<see cref="System.Runtime.CompilerServices.InternalsVisibleToAttribute"/> to make internals visible
					to a labs project is acceptable, and even recommended, as long as accessors and mocks are still not
					being used.  This enables experimentation, as well as integration and broad regression testing,
					of internal components.  Internal labs can also serve as simple, working examples of components and
					infrastructure for other developers to use as a reference.
				</item>
				<item>
					Labs do not have to follow any canonical structure in their code, unlike unit tests; e.g., arrange,
					act and assert.  Instead, labs should be written in exactly the same manner that a real consumer
					of the components should use them.  Experiments should be designed in a way that is recommended
					by the components' developers; i.e., assuming that proper usage will get the expected results.
					For your own compnents, labs should be designed to illustrate recommended usage without including
					isolated arrangement and assertions commonly found in unit tests, because labs are written with the
					assumption that the components under experimentation will work correctly.
				</item>
			</list>
		</remarks>
	</type>

</Lab>